//
//  WDEmptyView.swift
//  UIKitExtentions
//
//  Created by Alean on 2023/3/23.
//

import UIKit
private struct AssociatedKey {
    static var emptyKey: String = "emptyKey"
}

public extension UIView {
    public var emptyView: WDEmptyBaseView? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKey.emptyKey) as? WDEmptyBaseView
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKey.emptyKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            if let v = self.subviews.first { $0.isKind(of: WDEmptyBaseView.self) } as? WDEmptyBaseView {
                v.removeFromSuperview()
            }
            if let emptyView = emptyView {
                self.addSubview(emptyView)
            }
        }
    }
    
    func showEmpty() {
        emptyView?.isHidden = false
        if let emptyView = emptyView {
            self.bringSubviewToFront(emptyView)
        }
    }
    
    func hiddenEmpty() {
        emptyView?.isHidden = true

    }
}

open class WDEmptyModel: WDBaseModel {
    
}
open class WDEmptyViewModel: WDBaseViewModel<WDEmptyModel> {
    
}

open class WDEmptyBaseView: MVVMBaseView<WDEmptyViewModel> {
    public var actionTapBlock: (() -> Void)?
    
    public var image: UIImage? {
        didSet {
            setNeedsLayout()
        }
    }
    
    public var titleStr: String? {
        didSet {
            setNeedsLayout()
        }
    }
    
    public var detailStr: String? {
        didSet {
            setNeedsLayout()
        }
    }
    
    public var btnTitleStr: String? {
        didSet {
            setNeedsLayout()
        }
    }

    //内容距中心Y距离 默认为0 表示居中
    public var centerSpaceY: CGFloat = 0.0 {
        didSet {
            setNeedsLayout()
        }
    }
    private(set) var contentView: UIView = UIView()
    private(set) var target: AnyObject?
    private(set) var action: Selector?
    private(set) var actionBtnBlock: (() -> Void)?
    
    /*
     // Only override draw() if you perform custom drawing.
     // An empty implementation adversely affects performance during animation.
     override func draw(_ rect: CGRect) {
     // Drawing code
     }
     */
    deinit {
        if let tap = tap {
            removeGestureRecognizer(tap)
        }
    }

    open override func initContent() {
        super.initContent()
        initialize()
        prepare()
    }

    open override func layoutSubviews() {
        super.layoutSubviews()
        if self.frame == CGRect.zero {
            return
        }
        setupSubviews()
    }

    open override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        if let newSuperview = newSuperview as? UIView {
            var frame = self.frame
            frame.size.width = newSuperview.frame.size.width
            frame.size.height = newSuperview.frame.size.height
            self.frame = frame
        }
    }

    open func setupSubviews() {
    }

    open func initialize() {
    }

    open func prepare() {
        autoresizingMask = [.flexibleWidth, .flexibleHeight]
    }

    var tap: UITapGestureRecognizer?
    func creatEmptyView(customView: UIView? = nil) {
        if contentView.superview == nil {
            addSubview(contentView)
        }
        if let customView = customView {
            contentView.addSubview(customView)
        }
        if let tap = tap {
            removeGestureRecognizer(tap)
        }
        tap = UITapGestureRecognizer(target: self, action: #selector(tapEmptyView(_:)))
        addGestureRecognizer(tap!)
    }

    func creatEmptyView(image: UIImage? = nil,
                        titleStr: String? = nil,
                        detailStr: String? = nil,
                        btnTitleStr: String? = nil,
                        target: AnyObject? = nil,
                        action: Selector? = nil,
                        actionBtnBlock: (() -> Void)? = nil) {
        self.image = image
        self.titleStr = titleStr
        self.detailStr = detailStr
        self.btnTitleStr = btnTitleStr
        self.target = target
        self.action = action
        self.actionBtnBlock = actionBtnBlock
        creatEmptyView()
    }

    @objc func tapEmptyView(_ tap: UITapGestureRecognizer) {
        actionTapBlock?()
    }
}

public extension WDEmptyBaseView {
    static func creatEmptyView(customView: UIView) -> WDEmptyBaseView {
        let emptyView = self.init()
        emptyView.creatEmptyView(customView: customView)
        return emptyView
    }

    static func creatEmptyView(image: UIImage? = nil,
                               titleStr: String? = nil,
                               detailStr: String? = nil,
                               btnTitleStr: String? = nil,
                               target: AnyObject? = nil,
                               action: Selector? = nil,
                               actionBtnBlock: (() -> Void)? = nil) -> WDEmptyBaseView {
        let emptyView = self.init()
        emptyView.creatEmptyView(image: image, titleStr: titleStr, detailStr: detailStr, btnTitleStr: btnTitleStr, target: target, action: action, actionBtnBlock: actionBtnBlock)
        return emptyView
    }
}

open class WDEmptyDefaultView: WDEmptyBaseView {
    private lazy var promptImageView: UIImageView? = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit
        return imageView
    }()

    open var imageSize: CGSize?

    lazy var titleLabel: UILabel? = {
        let label = UILabel(title: "", numOfLines: 0, alignment: .center)
        label.textColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
        label.font = UIFont.systemFont(ofSize: 16, weight: .regular)
        return label
    }()
    
    lazy var detailLabel: UILabel? = {
        let label = UILabel(title: "", numOfLines: 0, alignment: .center)
        label.textColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
        label.font = UIFont.systemFont(ofSize: 16, weight: .regular)
        return label
    }()

    lazy var actionButton: UIButton? = {
        let btn = UIButton()
        btn.layer.masksToBounds = true
        btn.setTitleColor(UIColor.white, for: .normal)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        btn.backgroundColor = UIColor(red: 0.22, green: 0.8, blue: 0.56, alpha: 1)
        btn.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
        return btn
    }()

    var contentMaxWidth: CGFloat = 0.0 //最大宽度
    var contentWidth: CGFloat = 0.0 //内容物宽度
    var contentHeight: CGFloat = 0.0 //内容物高度
    var subViweMargin: CGFloat = 0.0 //内容物上每个子控件之间的间距

    open override func initialize() {
        
    }

    open override func prepare() {
        super.prepare()
    }

    open override func setupSubviews() {
        super.setupSubviews()
        contentMaxWidth = frame.size.width - 30.0
        contentWidth = 0
        contentHeight = 0

        if let image = self.image {
            if let promptImageView = promptImageView {
                if promptImageView.superview == nil {
                    contentView.addSubview(promptImageView)
                }
                promptImageView.image = image
                var imgViewWidth = image.size.width
                var imgViewHeight = image.size.height
                if let imageSize = imageSize {
                    if imgViewWidth > imgViewHeight {
                        imgViewHeight = (imgViewHeight / imgViewWidth) * imageSize.width
                        imgViewWidth = imageSize.width
                    } else {
                        imgViewWidth = (imgViewWidth / imgViewHeight) * imageSize.height
                        imgViewHeight = imageSize.height
                    }
                }
                promptImageView.frame = CGRect(x: 0, y: 0, width: imgViewWidth, height: imgViewHeight)
                
                contentWidth = promptImageView.frame.size.width
//               contentHeight = promptImageView.frame.origin.y + promptImageView.frame.size.height
                contentHeight = promptImageView.frame.maxY
            }
        } else {
            promptImageView?.removeFromSuperview()
//            promptImageView = nil
        }
        
        if let titleStr = titleStr, !titleStr.isEmpty {
            if let titleLabel = titleLabel {
                if titleLabel.superview == nil {
                    contentView.addSubview(titleLabel)
                }
                
                let font = titleLabel.font.pointSize > 0 ? titleLabel.font : UIFont.systemFont(ofSize: 16)
                let fontSize = font!.pointSize

                let size = sizeWithString(text: titleStr, size: CGSize(width: contentMaxWidth, height: fontSize + 5), font: font!)
                let width = size.width
                let height = size.height
                titleLabel.frame = CGRect(x: 0, y: contentHeight + 10, width: width, height: height);
                titleLabel.font = font
                titleLabel.text = titleStr
                
                contentWidth = width > contentWidth ? width : contentWidth
//                titleLabel.frame.origin.y + titleLabel.frame.size.height
                contentHeight = titleLabel.frame.maxY
            }
        } else {
            titleLabel?.removeFromSuperview()
//            titleLabel = nil
        }
        
        if let detailStr = detailStr, !detailStr.isEmpty {
            if let detailLabel = detailLabel {
                if detailLabel.superview == nil {
                    contentView.addSubview(detailLabel)
                }
                let font = detailLabel.font.pointSize > 0 ? detailLabel.font : UIFont.systemFont(ofSize: 14);
                let fontSize = font!.pointSize
//                detailLabel.font = font
//                detailLabel.text = detailStr
                let detailLabLineSpacing: CGFloat = 1
                let maxLines: CGFloat = 2
                let maxHeight = maxLines * (fontSize + 5) + (maxLines - 1) * detailLabLineSpacing

                let x = sizeWithAttributedString(string: detailStr, font: font!, lineSpacing: detailLabLineSpacing, maxSize: CGSizeMake(contentMaxWidth, maxHeight))
                detailLabel.attributedText = x.0
                let size = x.1
                detailLabel.frame = CGRect(x: 0, y: contentHeight + 20, width: size.width, height: size.height)
                contentWidth = size.width > contentWidth ? size.width : contentWidth
//                contentHeight = detailLabel.frame.origin.y + detailLabel.frame.size.height
                contentHeight = detailLabel.frame.maxY
            }
        } else {
            detailLabel?.removeFromSuperview()
//            detailLabel = nil
        }
        
        if let btnTitleStr = btnTitleStr, !btnTitleStr.isEmpty {
            if let actionButton = actionButton {
                if actionButton.superview == nil {
                    contentView.addSubview(actionButton)
                }
                let font = actionButton.titleLabel?.font.pointSize ?? 0 > 0 ? actionButton.titleLabel?.font : UIFont.systemFont(ofSize: 16, weight: .medium)
                let fontSize = font!.pointSize
                let textSize = sizeWithString(text: btnTitleStr, size: CGSizeMake(contentMaxWidth, fontSize), font: font!)
                let btnHeight: CGFloat = textSize.height + 16
                var btnWidth: CGFloat = textSize.width + 16
                btnWidth = btnWidth > 134 ? btnWidth : 150
                btnWidth = btnWidth > contentMaxWidth ? contentMaxWidth : btnWidth
                actionButton.frame = CGRect(x: 0, y: contentHeight + 20, width: btnWidth, height: btnHeight)
                actionButton.setTitle(btnTitleStr, for: .normal)
                actionButton.titleLabel?.font = font
                actionButton.layer.cornerRadius = btnHeight / 2.0

                if let target = target, let action = action {
                    actionButton.addTarget(target, action: action, for: .touchUpInside)
                }
                actionButton.addTarget(self, action: #selector(actionBtnClick(_:)), for: .touchUpInside)

                contentWidth = btnWidth > contentWidth ? btnWidth : contentWidth
//                contentHeight = actionButton.frame.origin.y + actionButton.frame.size.height
                contentHeight = actionButton.frame.maxY
            }
        } else {
            actionButton?.removeFromSuperview()
//            actionButton = nil
        }

        setSubViewFrame()
    }

    func setSubViewFrame() {
        let originEmptyWidth: CGFloat = self.frame.size.width
        let originEmptyHeight: CGFloat = self.frame.size.height
        let emptyViewCenterX: CGFloat = originEmptyWidth * 0.5
        let emptyViewCenterY: CGFloat = originEmptyHeight * 0.5
        self.center = CGPoint(x: emptyViewCenterX, y: emptyViewCenterY)

        var frame = contentView.frame
        frame.size = CGSize(width: contentWidth, height: contentHeight)
        contentView.frame = frame
//        contentView.center = CGPoint(x: contentWidth*0.5, y: contentHeight*0.5)
        contentView.center = CGPoint(x: emptyViewCenterX, y: emptyViewCenterY + centerSpaceY)

        let centerX: CGFloat = contentView.frame.size.width * 0.5
        
        if let promptImageView = promptImageView {
            var center: CGPoint = promptImageView.center
            center.x = centerX
            promptImageView.center = center;
        }

        if let titleLabel = titleLabel {
            var center: CGPoint = titleLabel.center
            center.x = centerX
            titleLabel.center = center
        }
        if let detailLabel = detailLabel {
            var center: CGPoint = detailLabel.center
            center.x = centerX
            detailLabel.center = center
        }
        if let actionButton = actionButton {
            var center: CGPoint = actionButton.center
            center.x = centerX
            actionButton.center = center
        }

    }

    @objc func actionBtnClick(_ sender: UIButton) {
        actionBtnBlock?()
    }
}

public extension WDEmptyDefaultView {
    func sizeWithString(text: String,
                      size: CGSize,
                      font: UIFont) -> CGSize {
        let size = text.boundingRect(with: size,
                                     options: .usesLineFragmentOrigin,
                                     attributes: [NSAttributedString.Key.font : font],
                                     context: nil).size
        return size
    }
    
    func sizeWithAttributedString(string: String,
                                  font: UIFont,
                                  lineSpacing: CGFloat,
                                  maxSize: CGSize) -> (NSMutableAttributedString, CGSize) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineBreakMode = .byWordWrapping
        paragraphStyle.lineSpacing = lineSpacing // 设置行间距
        paragraphStyle.alignment = .center

        let attributedStr = NSMutableAttributedString(
            string: string,
            attributes: [
                NSAttributedString.Key.paragraphStyle: paragraphStyle,
                NSAttributedString.Key.font:font]
        )
        let size = attributedStr.boundingRect(with: maxSize,
                                              options: [.usesLineFragmentOrigin, .usesFontLeading],
                                              context: nil).size
        return (attributedStr, size)
    }

}
